﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Demo.Mmose.Common.Util;

namespace Demo.Mmose.Common.Atom
{
    public class AtomicBoolean : IAtomOperator<bool>
    {
        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 
        /// </summary>
        private AtomicBoolean()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="atomicBoolean"></param>
        private AtomicBoolean( bool atomicBoolean )
        {
            m_AtomicBoolean = atomicBoolean ? 1 : 0;
        }
        #endregion

        #region zh-CHS 属性 | en Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private int m_AtomicBoolean = 0;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public bool Value
        {
            get { return m_AtomicBoolean == 0 ? false : true; }
        }
        #endregion

        #region zh-CHS 接口实现 | en Interface Implementation
        /// <summary>
        /// 以原子方式将给定值与当前值相加。
        /// </summary>
        /// <param name="addValue"></param>
        /// <returns></returns>
        public void Add( bool addValue )
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将给定值与当前值相减。
        /// </summary>
        /// <param name="subtractValue"></param>
        /// <returns></returns>
        public void Subtract( bool subtractValue )
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将给定值与当前值相乘。
        /// </summary>
        /// <param name="multiplyValue"></param>
        /// <returns></returns>
        public void Multiply( bool multiplyValue )
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将给定值与当前值相除。
        /// </summary>
        /// <param name="divideValue"></param>
        /// <returns></returns>
        public void Divide( bool divideValue )
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式设置为给定值。
        /// </summary>
        /// <param name="assignmentValue"></param>
        /// <returns></returns>
        public void Assignment( bool assignmentValue )
        {
            int oldAtomicBoolean;
            int newAtomicBoolean;

            do
            {
                oldAtomicBoolean = m_AtomicBoolean;
                newAtomicBoolean = assignmentValue ? 1 : 0;

            } while ( Interlocked.CompareExchange( ref m_AtomicBoolean, newAtomicBoolean, oldAtomicBoolean ) != oldAtomicBoolean );
        }

        /// <summary>
        /// 如果当前值 == 预期值，则以原子方式将该值设置为给定的更新值。
        /// </summary>
        /// <param name="setValue"></param>
        /// <param name="compareValue"></param>
        /// <returns></returns>
        public bool CompareExchange( bool setValue, bool compareValue )
        {
            int iSetValue = setValue ? 1 : 0;
            int iCompareValue = compareValue ? 1 : 0;

            return Interlocked.CompareExchange( ref m_AtomicBoolean, iSetValue, iCompareValue ) == iCompareValue;
        }

        /// <summary>
        /// 以原子方式将当前值减 1 ( -- )
        /// </summary>
        /// <returns></returns>
        public void Decrement()
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将当前值加 1 ( ++ )
        /// </summary>
        /// <returns></returns>
        public void Increment()
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将当前值左移 ( << )
        /// </summary>
        /// <returns></returns>
        public void LeftShift( int leftShift )
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将当前值右移 ( >> )
        /// </summary>
        /// <returns></returns>
        public void RightShift( int rightShift )
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将当前值求正(一元操作) ( + )
        /// </summary>
        /// <param name="addValue"></param>
        /// <returns></returns>
        public void Plus()
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将当前值求负(一元操作) ( - )
        /// </summary>
        /// <param name="addValue"></param>
        /// <returns></returns>
        public void Minus()
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将当前值取反(一元操作) ( ! )
        /// </summary>
        /// <param name="addValue"></param>
        /// <returns></returns>
        public void Invert()
        {
            int oldAtomicBoolean;
            int newAtomicBoolean;

            do
            {
                oldAtomicBoolean = m_AtomicBoolean;
                newAtomicBoolean = m_AtomicBoolean == 0 ? 1 : 0;

            } while ( Interlocked.CompareExchange( ref m_AtomicBoolean, newAtomicBoolean, oldAtomicBoolean ) != oldAtomicBoolean );
        }

        /// <summary>
        /// 以原子方式将当前值求补 ( ~ )
        /// </summary>
        /// <returns></returns>
        public void OneComplement()
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将当前值按位与 ( &= )
        /// </summary>
        /// <returns></returns>
        public void BitwiseAND( bool bitwiseAnd )
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将当前值按位或 ( |= )
        /// </summary>
        /// <returns></returns>
        public void BitwiseInclusiveOR( bool inclusiveOR )
        {
            throw new NotSupportedException();
        }

        /// <summary>
        /// 以原子方式将当前值按位异或 ( ^= )
        /// </summary>
        /// <returns></returns>
        public void BitwiseExclusiveOR( bool exclusiveOR )
        {
            throw new NotSupportedException();
        }
        #endregion

        #region zh-CHS 共有委托 | en Public Delegate
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<UpdatingValue<bool>> m_EventUpdatingValue;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockEventUpdating = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<UpdatingValue<bool>> UpdatingValue
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockEventUpdating );
                {
                    m_EventUpdatingValue += value;
                }
                m_LockEventUpdating.Exit();
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockEventUpdating );
                {
                    m_EventUpdatingValue -= value;
                }
                m_LockEventUpdating.Exit();
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<UpdatedValue<bool>> m_EventUpdatedValue;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockEventUpdated = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<UpdatedValue<bool>> UpdatedValue
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockEventUpdated );
                {
                    m_EventUpdatedValue += value;
                }
                m_LockEventUpdated.Exit();
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockEventUpdated );
                {
                    m_EventUpdatedValue -= value;
                }
                m_LockEventUpdated.Exit();
            }
        }
        #endregion

        #region zh-CHS 方法 | en Method
        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public static bool operator ==( AtomicBoolean atomicBooleanA, AtomicBoolean atomicBooleanB )
        {
            return atomicBooleanA.m_AtomicBoolean == atomicBooleanB.m_AtomicBoolean;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public static bool operator ==( AtomicBoolean atomicBooleanA, bool atomicBooleanB )
        {
            return atomicBooleanA.Value == atomicBooleanB;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public static bool operator !=( AtomicBoolean atomicBooleanA, AtomicBoolean atomicBooleanB )
        {
            return atomicBooleanA.m_AtomicBoolean != atomicBooleanB.m_AtomicBoolean;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        public static bool operator !=( AtomicBoolean atomicBooleanA, bool atomicBooleanB )
        {
            return atomicBooleanA.Value != atomicBooleanB;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iSerial"></param>
        /// <returns></returns>
        public static explicit operator bool( AtomicBoolean atomicBoolean )
        {
            return atomicBoolean.Value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="atomicBoolean"></param>
        /// <returns></returns>
        public static implicit operator AtomicBoolean( bool atomicBoolean )
        {
            return new AtomicBoolean( atomicBoolean );
        }
        #endregion

        #region zh-CHS 方法覆盖 | en Method Overrides
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return m_AtomicBoolean.ToString();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return m_AtomicBoolean.GetHashCode();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xObject"></param>
        /// <returns></returns>
        public override bool Equals( object xObject )
        {
            AtomicBoolean atomicInt = xObject as AtomicBoolean;
            if ( atomicInt == null )
                return false;

            return atomicInt.m_AtomicBoolean == m_AtomicBoolean;
        }
        #endregion
    }
}
